home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Documents / NeXTAnswers / appkit.731 < prev    next >
Text File  |  1992-02-06  |  6KB  |  150 lines

  1. {\rtf0\ansi{\fonttbl\f0\fnil Times-Roman;\f2\fmodern Courier;\f1\fswiss Helvetica;}
  2. \paperw13040
  3. \paperh10140
  4. \margl120
  5. \margr120
  6. {\colortbl\red0\green0\blue0;}
  7. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f0\b0\i0\ul0\fs28 single pixel read\
  8. \
  9. Q:  I want to read some specific pixel values from a window.  How do I do that? \
  10. \
  11.  
  12. \fi-440\li440 A:  Here's the code for the function 
  13. \b colorAt
  14. \b0 () which will return the color of a pixel in an instance of NXBitmapImageRep.  If you want to read the pixel off of a window, you would first lock the focus in an appropriate view of the window, then use:\
  15.  
  16. \fi0\li0 \
  17.  
  18. \pard\tx620\tx1240\tx1860\tx2480\tx3100\tx3720\tx4340\tx4980\tx5600\tx6220\f2\fs24\fc0     NXRect rect = \{\{0.0, 0.0\}, \{4.0, 4.0\}\};\
  19.     id image = [[NXBitmapImageRep alloc] initData:NULL fromRect:&rect];\
  20.     NXColor colorAtSomeLoc = colorAt(image, x, y);\
  21.     [image free];\
  22.  
  23. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f0\fs28 \
  24.  
  25. \pard\tx620\tx1240\tx1860\tx2480\tx3100\tx3720\tx4340\tx4980\tx5600\tx6220\fc0 Here rect is the rectangle for which you want to get the pixels from the window server to the app.  Of course, if all you need to do is read one pixel from a window, then set rect to \{\{x, y\}, \{1, 1\}\} and look at the color at location 0, 0.\
  26. \
  27. You can do the same thing for an NXImage: lock focus on it and using the above method read a pixel.  Or, better yet, if you want to read pixels from a TIFF file you can directly use the NXBitmapImageRep without having to read pixels back from the window server.\
  28. \
  29. Here's the routine.  If it is too complicated or too slow (which it might end up being, if you want to run in a loop over zillions of pixels), you can remove some of the fluff code like conversion of raw data value to an NXColor() and even alpha computation...  \
  30.  
  31. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600 \
  32.  
  33. \pard\tx620\tx1240\tx1860\tx2480\tx3100\tx3720\tx4340\tx4980\tx5600\tx6220\f2\fs24\fc0 #import <appkit/color.h>\
  34. #import <appkit/graphics.h>\
  35. #import <appkit/NXBitmapImageRep.h>\
  36. \
  37. /* Returns the color at a certain pixel location in a bitmap. */\
  38. /* This version assumes the bitmap is 1, 2, 4, or 8 bps deep  */\
  39. /* and its either grayscale or RGB. */\
  40. \
  41. NXColor colorAt(NXBitmapImageRep *image, int x, int y)\
  42. \{\
  43.     int sampleCnt, bps, spp, amask;\
  44.     unsigned char *planes[5], data[5];\
  45.     NXColorSpace colorSpace;\
  46. \
  47.     spp = [image samplesPerPixel];\
  48.     bps = [image bitsPerSample];\
  49.     colorSpace = [image colorSpace];\
  50. \
  51. #ifdef CHECK_VALIDITY\
  52.     if ((bps != 1 && bps != 2 && bps != 4 && bps != 8) ||\
  53.        (colorSpace != NX_RGBColorSpace || \
  54.         colorSpace != NX_OneIsBlackColorSpace || \
  55.         colorSpace != NX_OneIsWhiteColorSpace)) \
  56.     \{\
  57.         NXLogError ("colorAt() can't deal with provided image.\\n");\
  58.         return NX_COLORCLEAR;\
  59.     \}\
  60. #endif\
  61. #ifdef CHECK_RANGE\
  62.     if ((x < 0) || (y < 0) || (x >= [image pixelsWide]) || \
  63.         (y >= [image pixelsHigh])) \
  64.     \{\
  65.         NXLogError ("Pixel out of bounds in colorAt().\\n");\
  66.         return NX_COLORCLEAR;\
  67.     \}\
  68. #endif\
  69. \
  70.     [image getDataPlanes:planes];\
  71.    \
  72.     amask = (1 << bps) - 1;    /* 1, 3, 15, 255 for bps = 1, 2, 4, 8 */\
  73. \
  74.     /* Get the samples into the data[] array. */\
  75.     if ([image isPlanar]) \
  76.     \{\
  77.         int pixel = x * bps;\
  78.         int byteLoc = [image bytesPerRow] * y + (pixel >> 3);\
  79.         int bitLoc = pixel & 7;\
  80.         for (sampleCnt = 0; sampleCnt < spp; sampleCnt++) \
  81.         \{\
  82.             data[sampleCnt] = \
  83.                 ((*(planes[sampleCnt]+byteLoc)) >> (8 - bitLoc - bps)) & amask;\
  84.         \}\
  85.     \} \
  86.     else \
  87.     \{\
  88.         unsigned char *byteLoc = planes[0] + [image bytesPerRow] * y;\
  89.         int bitLoc = x * bps * spp;\
  90.         for (sampleCnt = 0; sampleCnt < spp; sampleCnt++) \
  91.         \{\
  92.             data[sampleCnt] = \
  93.                ((byteLoc[bitLoc >> 3]) >> (8 - (bitLoc & 7) - bps)) & amask;\
  94.             bitLoc += bps;\
  95.         \}\
  96.     \}\
  97. \
  98.     /* If no alpha, set it to opaque and increment spp. */\
  99.     /* Otherwise, compute the true color values (by un-premultipling). */\
  100. \
  101.     if (![image hasAlpha]) \
  102.     \{\
  103.         data[spp] = amask;\
  104.         spp++;\
  105.     \} \
  106.     else if (data[spp - 1] && data[spp - 1] != amask) \
  107.     \{\
  108.         for (sampleCnt = 0; sampleCnt < spp - 1; sampleCnt++) \
  109.         \{\
  110.             data[sampleCnt] = \
  111.                (unsigned char)(0.5 + amask * \
  112.                ( ((float)(data[sampleCnt])) / (data[spp - 1]) ));\
  113.         \}\
  114.     \}\
  115. \
  116.     /* At this point data[] contains spp samples, right justified  */\
  117.     /* within the range 0..amask.  We can either return those, or  */\
  118.     /* return them in a normalized fashion (in the range 0..255,   */\
  119.     /* after shifting them over to the left by multiplying them by */\
  120.     /* 255/amask), or we can return an NXColor. The latter is less */\
  121.     /* efficient, probably, but most abstract.   */\
  122. \
  123.     switch (colorSpace) \
  124.     \{\
  125.     case NX_RGBColorSpace:\
  126.         return NXConvertRGBAToColor(((float)data[0]) / amask, \
  127.                                      ((float)data[1]) / amask, \
  128.                                  ((float)data[2]) / amask, \
  129.                 [image hasAlpha] ? ((float)data[3]) / amask : NX_NOALPHA);\
  130.                 \
  131.     case NX_OneIsWhiteColorSpace:\
  132.         return NXConvertGrayAlphaToColor(((float)data[0]) / amask, \
  133.                         [image hasAlpha] ? ((float)data[1]) / amask : NX_NOALPHA);\
  134.                     \
  135.     case NX_OneIsBlackColorSpace:\
  136.         return NXConvertGrayAlphaToColor(((float)(amask - data[0])) / amask, \
  137.                         [image hasAlpha] ? ((float)(amask - data[1])) / amask :\
  138.                     NX_NOALPHA);\
  139.     \}\
  140. \}
  141. \f1\fs28 \
  142.  
  143. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f0 \
  144. QA731\
  145. \
  146. Not valid for 1.0\
  147. Valid for 2.0\
  148. \
  149.  
  150.